package org.idea.qiyu.framework.canal.handle;

import com.alibaba.otter.canal.protocol.CanalEntry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * 基于canal的数据处理器
 *
 * @author idea
 * @data 2019/10/13
 */
public class CanalDataTypeConvertHandler extends AbstractTypeConvertHandler{

    private static final Logger LOGGER = LoggerFactory.getLogger(CanalDataTypeConvertHandler.class);

    /**
     * 将binlog的记录解析为一个bean对象
     *
     * @param columnList
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T convertToBean(List<CanalEntry.Column> columnList, Class<T> clazz) {
        T bean = null;
        try {
            bean = clazz.newInstance();
            Field[] fields = clazz.getDeclaredFields();
            Field.setAccessible(fields, true);
            Map<String, Field> fieldMap = new HashMap<>(fields.length);
            for (Field field : fields) {
                fieldMap.put(field.getName().toLowerCase(), field);
            }
            if (fieldMap.containsKey("serialVersionUID")) {
                fieldMap.remove("serialVersionUID".toLowerCase());
            }
            for (CanalEntry.Column column : columnList) {
                String columnName = column.getName();
                String columnValue = column.getValue();
                if (fieldMap.containsKey(columnName)) {
                    //基础类型转换不了
                    Field field = fieldMap.get(columnName);
                    Class<?> type=field.getType();
                    switch (BEAN_FIELD_TYPE.get(type)){
                        case "java.lang.Integer":
                        case "int":
                            field.set(bean,parseToInteger(columnValue));
                            break;
                        case "java.lang.Long":
                        case "long":
                            field.set(bean,parseToLong(columnValue));
                            break;
                        case "java.lang.Double":
                        case "double":
                            field.set(bean,parseToDouble(columnValue));
                            break;
                        case "short":
                            field.set(bean,parseToShort(columnValue));
                            break;
                        case "java.lang.Float":
                        case "float":
                            field.set(bean,parseToFloat(columnValue));
                            break;
                        case "java.lang.String":
                            field.set(bean,columnValue);
                            break;
                        case "java.handle.Date":
                            field.set(bean, parseToDate(columnValue));
                            break;
                        case "java.sql.Date":
                            field.set(bean, parseToSqlDate(columnValue));
                            break;
                        case "java.sql.Timestamp":
                            field.set(bean, parseToTimestamp(columnValue));
                            break;
                        case "java.sql.Time":
                            field.set(bean, parseToSqlTime(columnValue));
                            break;
                    }
                }
            }
        } catch (InstantiationException | IllegalAccessException e) {
            LOGGER.error("[CanalDataHandler]convertToBean，初始化对象出现异常，对象无法被实例化,异常为{}", e);
        }
        return bean;
    }

}